余烬缀记

基于 Docker Alpine 镜像运行 Rust

edited on:

本文采用两阶段构建 Rust 镜像包,有利于减少包体积,构建和运行环境均采用 alpine

# 第一阶段:构建 Rust 应用程序  
FROM rust:alpine AS builder  

# 设置工作目录  
WORKDIR /app  

# 安装一些依赖  
RUN apk update && apk add --no-cache -U musl-dev

# 复制 src 目录  
COPY src/ ./src/  

# 复制 Cargo.toml 和 Cargo.lock
COPY Cargo.toml Cargo.lock ./  

# 构建 Rust 应用程序  
RUN cargo build --release  

# 第二阶段:创建最终镜像  
FROM alpine:latest  

# 设置工作目录  
WORKDIR /var/www/app  

# 从第一阶段复制构建生成的可执行文件到最终镜像  
COPY --from=builder /app/target/release/my_rust_app .  

RUN apk update && apk add --no-cache -U libgcc  

# 运行Rust应用程序  
CMD ["./my_rust_app"]

# 遇到的错误

  • Failed to run custom build command for ring v0.16.20

第一阶段构建时添加

RUN apk update && apk add --no-cache -U musl-dev
  • Error loading shared library libgcc_s.so.1: No such file or directory

第二阶段添加 libgcc

RUN apk update && apk add --no-cache -U libgcc
  • Segmentation fault 错误

基于 Docker alpine 镜像构建 Rust 环境在发送网络请求时会抛出:

Segmentation fault

切换到 Debian 没有这个错误,通过 bing 搜索得知是 Alpine 的 OpenSSL 依赖问题导致,该问题同 how-to-resolve-a-segmentation-fault-in-a-multithreaded-rust-application-in-alpin 一致

解决:

reqwest 使用 rusts-tls 替代 OpenSSL

reqwest = { version = "0.11", default-features = false, features = ["rustls-tls"] }